import { HashConstructor, StreamHasher } from "@smithy/types";
import { fileIo as fs } from '@kit.CoreFileKit';
import { HashCalculator } from "./HashCalculator";

// ToDo: deprecate in favor of readableStreamHasher
/**
 * @internal
 */
export const fileStreamHasher: StreamHasher<fs.ReadStream> = (hashCtor: HashConstructor, fileStream: fs.ReadStream) =>
  new Promise((resolve, reject) => {
    if (!isReadStream(fileStream)) {
      reject(new Error("Unable to calculate hash for non-file streams."));
      return;
    }

    const fileStreamTee = fs.createReadStream(fileStream.path, {
      start: (fileStream as any).start,
      end: (fileStream as any).end,
    });

    const hash = new hashCtor();
    const hashCalculator = new HashCalculator(hash);

    fileStreamTee.pipe(hashCalculator);
    fileStreamTee.on("error", (err: any) => {
      // if the source errors, the destination stream needs to manually end
      hashCalculator.end();
      reject(err);
    });
    hashCalculator.on("error", reject);
    hashCalculator.on("finish", function (this: HashCalculator) {
      hash.digest().then(resolve).catch(reject);
    });
  });

const isReadStream = (stream: fs.ReadStream): stream is fs.ReadStream => typeof (stream as fs.ReadStream).path === "string";
